home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
151-175
/
disk_154
/
disklib
/
lib.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-06
|
13KB
|
499 lines
/***************************************************************
*
* Lib.c
*
* Disk Library Documentation System
* Main Program
*
* By Wilson Snyder (c) January 1988
*
****************************************************************
*
* NOTICE:
*
* This program was written as a service to the amiga
* users. This program may be used by all parties, including
* sale (see below) as long as the author's name and address
* remains intact in the program and documentation.
* Distribution of this program by parties selling it
* as part of a commercial for-profit package of over $10
* must contact the address below before such a package is sold.
*
* I make no warranties over this program, performance,
* etc. And any costs incurred by this program, or its
* actions are placed on the user.
*
* PLEASE FORWARD INPROVEMENTS MADE TO THIS PROGRAM TO:
*
* Wilson Snyder, 15 Davis Parkway, South Burlington, VT 05403
*
****************************************************************
*
* AddName and base for Process taken from the TSIZE
* utility written by the excellent work of the
* Software Distillery.
*
****************************************************************/
#include "libraries/dosextens.h"
#include "ctype.h"
#include "stdio.h"
#define VERSION "AMIGA-LIB. Version 1.0.2. By Wilson Snyder"
#define DESC "$$DES$$"
#define PERSUB 8 /* Characters to indent per subdirectory */
#define INFOIND 8 /* Indent for description and filesize */
#define RM 75 /* Right margin */
#define LM 0 /* Left margin */
#define TM 1 /* Top margin */
#define HM 2 /* Header margin (lines after header) */
#define LINES 60 /* Lines per page */
BPTR Lock(); /* Define functions... */
BOOL Examine();
BOOL ExNext();
char path [256]; /* Current search path */
char header [80]; /* Header for top line */
BOOL prtsize = FALSE; /* Print the path size information */
BOOL prtheader = FALSE; /* Print the header and page breaks */
struct Sortem { /* Linked list for insertion sort of directory names */
char FileName[108]; /* Directory name */
struct Sortem *Next; /* Pointer to next */
};
/***************************************************************
* ADDNAME
*
* Add filename to the end of the current path.
*
* Routine taken from from TSIZE utility by the Software Distillery.
***************************************************************/
int AddName(name, len)
register char *name;
int len;
{
register char *p; /* current position in path */
register int i = 0; /* added length counter */
char ch; /* last character of current path */
p = path + len;
/* add a slash between path and name if legal */
if (len != 0 && (ch = path[len-1]) != '/' && ch != ':') {
*p++ = '/';
i++;
}
/* copy name to end of path (including null terminator) */
while (*p++ = *name++) i++;
/* return new length of path */
return (len + i);
}
/***************************************************************
* FILECMP
* Compare two filenames for sort routine (case insensitive.)
***************************************************************/
int filecmp(a,b)
char *a,*b;
{
for (;toupper(*a)==toupper(*b);a++,b++)
if (*a=='\0') return (0);
return (toupper(*a)-toupper(*b));
}
/***************************************************************
* INDENT
* Indent a number of spaces. Outputted to stdout.
***************************************************************/
void Indent(num)
int num;
{
while (num--) putchar (' ');
}
/***************************************************************
* HEADER
* Print header every so many lines.
***************************************************************/
void Header(inc)
int inc;
{
static int linecount; /* Number of lines down */
static int page; /* Current page number */
int t; /* Temp */
if (inc)
linecount += inc;
else {
/* 0 increment resets information */
linecount = 0;
page = 0;
}
if (linecount>LINES && prtheader) {
/* Time to print the header */
putchar ('\f');
page++;
for (t=TM;t;t--) putchar ('\n');
printf (header,page);
for (t=HM;t;t--) putchar ('\n');
linecount = TM + HM + 1;
}
}
/***************************************************************
* ROOT
* Print information for the page header
***************************************************************/
BOOL Root()
{
struct FileInfoBlock *info; /* pointer to file info */
BPTR lock; /* pointer to file lock */
int t,loc; /* temp stuff */
/* allocate an info block (must be longword alligned) */
if (!(info = (struct FileInfoBlock *)
AllocMem(sizeof(struct FileInfoBlock), 0))) {
printf ("Out of memory.\n");
return (TRUE);
}
/* try to obtain lock on current file */
if (!(lock = Lock(path, ACCESS_READ))) {
printf ("Invalid file or directory, '%s'.\n", path);
FreeMem(info, sizeof(struct FileInfoBlock));
return (TRUE);
}
/* get information on file or directory associated with lock */
if (!Examine(lock, info)) {
printf ("Error examining locked file or directory.\n");
UnLock(lock);
FreeMem(info, sizeof(struct FileInfoBlock));
return (TRUE);
}
/* Make sure user specified a directory, not a file */
if (info->fib_DirEntryType <= 0) {
printf ("Must specify a directory, not a file.\n");
UnLock(lock);
FreeMem(info, sizeof(struct FileInfoBlock));
return (TRUE);
}
/* Build Header line (will be used with printf) */
loc = 0;
for (t=LM;t;t--) header[loc++] = ' ';
strcpy (&header[loc], "Page %-4d");
loc += 9;
for (t=RM-loc-strlen(info->fib_FileName);t;t--) header[loc++] = ' ';
strcpy (&header[loc],info->fib_FileName);
loc += strlen(info->fib_FileName);
header[loc++] = '\n';
header[loc] = '\0';
/* Initalize header printer, then force header printing */
Header (0);
Header (LINES+2);
UnLock(lock);
FreeMem(info, sizeof(struct FileInfoBlock));
return (FALSE);
}
/***************************************************************
* BOTTOM
* Display size information at bott
om of directory.
***************************************************************/
void Bottom (depth,size,found)
int depth;
long size;
BOOL found;
{
if (prtsize) {
Indent (depth*PERSUB+INFOIND+LM);
printf ("Total size %ld bytes.\n", size);
if (found) printf ("\n");
Header (2);
}
}
/***************************************************************
* DISPLAY
* Display information from the DESC file in the directory.
***************************************************************/
BOOL Display (depth,dirname)
int depth;
char *dirname;
{
FILE *desc; /* DESCription file info */
BOOL found; /* Found a description file */
int lineloc; /* Location on the output line */
int wordlen; /* Length of word in the buffer */
char wordstore[RM+10]; /* Storage for current word */
BOOL Cont; /* & encountered, ignore return */
BOOL Long; /* Long line/word just printed */
char ch; /* Character from file */
int t,lm; /* temp */
/* Print directory name */
Header (2);
Indent (depth*PERSUB+LM);
printf ("%s\n", dirname);
/* Add DESC filename to path, attempt to open the file */
t = strlen(path);
AddName (DESC,t);
found = ((desc=fopen(path,"r"))!=0);
/* If found, justify the file on the way out */
if (found) {
lm = depth*PERSUB+INFOIND+LM;
lineloc = lm;
Indent (lm);
wordlen = 0;
Cont = FALSE;
Long = FALSE;
/* Process one character at a time */
while ((ch=getc(desc))!=EOF) {
/* Ignore return if proceded by a & */
if ((ch=='\n') && Cont) {
Cont = FALSE;
continue;
}
if (Cont) { /* & not proceded by a return */
wordstore[wordlen++] = '&';
Cont = FALSE;
}
/* Dump out the current word */
if (ch==' ' || ch=='\n') {
wordstore[wordlen] = '\0';
printf ("%s ",wordstore);
lineloc += wordlen + 1;
wordlen = 0;
if (Long || ch=='\n') {
putchar ('\n');
Header(1);
Indent (lm);
lineloc = lm;
Long = FALSE;
}
continue;
}
/* Force return if line goes over right margin */
if (((wordlen+lineloc)>RM) || (wordlen>(RM-lm))) {
if (wordlen>(RM-lm)) {
wordstore[wordlen] = '\0';
printf ("%s",wordstore);
wordlen = 0;
Long = TRUE;
}
putchar ('\n');
Header(1);
Indent (lm);
lineloc = lm;
}
/* Check for continuation character */
if (ch=='&') Cont = TRUE;
else wordstore[wordlen++] = ch;
}
fclose (desc);
/* Dump out any remaining word in the buffer */
if (wordlen) {
wordstore[wordlen] = '\0';
puts (wordstore);
putchar ('\n');
Header (1);
lineloc=0;
}
if (lineloc>lm) putchar('\n');
putchar('\n');
}
/* Restore path, return status if file was found */
path[t] = '\0';
return (found);
}
/*************************************************************
* PROCESS
*
* Find the size of a directory tree by adding the sizes
* of all files in the directory and all of its subdirectories.
*
* General directory searching concept taken from TSIZE
* utility by the Software Distillery.
************************************************************/
long Process(len,depth)
int len; /* Length of path name */
int depth; /* Number of directories down */
{
struct FileInfoBlock *info = NULL; /* pointer to file info */
struct Sortem *sort_top = NULL; /* top of sort list */
struct Sortem *sort_cur = NULL; /* current sort list loc */
struct Sortem *sort_tmp = NULL; /* current sort temp loc */
struct Sortem *sort_last= NULL; /* last sort temp loc */
long size = 0; /* running total of file size */
BPTR lock; /* pointer to file lock */
BOOL found; /* found DESC file */
/* Try to obtain lock on current directory */
if (!(lock = Lock(path, ACCESS_READ))) {
printf ("Invalid directory, '%s'.\n", path);
goto EXIT;
}
/* Allocate an info block (must be longword alligned) */
if (!(info = (struct FileInfoBlock *)
AllocMem(sizeof(struct FileInfoBlock), 0))) {
printf ("Out of memory.\n");
goto EXIT;
}
/* Get information on file or directory associated with lock */
if (!Examine(lock, info)) {
printf ("Error examining locked directory.\n");
goto EXIT;
}
/* This should not happen, but... */
if (info->fib_DirEntryType <= 0) {
printf ("Locked a file, not directory.\n");
goto EXIT;
}
/* Display top of directory header */
found = Display (depth,info->fib_FileName);
/* Read this directory */
while (ExNext(lock, info)) {
/* This is a directory */
if (info->fib_DirEntryType > 0) {
/* sub-directory, allocate sortem node */
if (!(sort_cur = (struct Sortem *)
AllocMem(sizeof(struct Sortem), 0))) {
printf ("Out of memory.\n");
break;
}
strcpy(sort_cur->FileName,info->fib_FileName);
sort_cur->Next = NULL;
/* Alphabetical insertion sort */
/* Find insertion location for new node */
for (sort_tmp = sort_top; sort_tmp;
sort_tmp = sort_tmp->Next) {
if (filecmp(sort_tmp->FileName,info->fib_FileName)>0)
break;
sort_last = sort_tmp;
}
/* Insert the node */
if (sort_tmp==sort_top) {
sort_cur->Next = sort_top;
sort_top = sort_cur;
}
else if (!sort_tmp) {
sort_cur->Next = NULL;
sort_last->Next = sort_cur;
}
else {
sort_cur->Next = sort_last->Next;
sort_last->Next = sort_cur;
}
sort_cur = NULL;
}
else /* found a file, just add size */
size += info->fib_Size;
}
/* Transverse sorted list, process then deallocate the node */
for (sort_tmp = sort_top; sort_tmp; sort_tmp = sort_last) {
size += Process(AddName(sort_tmp->FileName, len),depth+1);
sort_last = sort_tmp->Next;
FreeMem(sort_tmp, sizeof(struct Sortem));
}
/* Repair path */
path[len] = '\0';
/* Print bottom of directory information */
Bottom (depth, size, found);
EXIT:
if (info) FreeMem(info, sizeof(struct FileInfoBlock));
if (lock) UnLock(lock);
return(size);
}
/***************************************************************
* MAIN
***************************************************************/
main(argc, argv)
int argc;
char *argv[];
{
int len; /* Length of file name given on command line */
int t; /* Temp variable */
/* Help information */
if (argv[1][0]=='?') {
printf ("%s\nUseage: %s [Read-Path] [-size]\n",
VERSION, argv[0]);
exit (0);
}
/* parse command line (len used as temp param counter) */
for (len=1;len<argc;len++)
if (argv[len][0]=='-') { /* switch */
switch (toupper(argv[len][1])) {
case 'S': /* Size Flag */
prtsize = TRUE;
break;
case 'H': /* Header Flag */
prtheader = TRUE;
break;
/* ADD OTHER SWITCHES HERE */
default:
printf ("Bad Switch.\n");
}
/* Drop this argument */
argc--;
for (t=len;t<argc;t++) argv[t] = argv[t+1];
}
/* Process pathname */
if (argc>1)
len = AddName(argv[1], 0);
else len = AddName(":", 0);
/* Check root info, exit if invalid */
if (Root()) return(20);
/* Process root directory */
(void)Process(len,0);
EXIT:
return(0);
}